package utilities;

import interfaces.Node;
import interfaces.Transition;
import java.util.List;

/**
 *
 * @author Ricardo Sansores
 */
public class DotLanguageHelper {
    private static final String BLANK_SPACE = " ";

    private static final String DOT_FOOTER_TEMPLATE = "}";        
    private static final String LABEL_CLOSER = "\" ];\n";
    private static final String LABEL_OPENER = " [ label = \"";
    private static final String TRANSITION_CHAR = " -> ";
    private static final String TAB_CHAR = "\t";
    private static final String INVISIBLE_NODE_NAME = "EMPTY";
    
    private static final String DOT_HEADER_TEMPLATE = "digraph finite_state_machine {\n"
            + "\trankdir=LR;\n"
            + "\tsize=\"42,42\"\n"
            + "\t"+INVISIBLE_NODE_NAME+" [style=invis]"
            + "\t"+INVISIBLE_NODE_NAME+" [shape=point]"
            + "\tnode [shape = doublecircle]; ";

    private static final String DOT_BODY_TEMPLATE =";\n"
            + "\tnode [shape = circle];\n";                

    private List<? extends Node> doubleCircleNodes;
    private Node firstNode;
    private List<? extends Node> nodes;
    
    public DotLanguageHelper(Node firstNode, List<? extends Node> doubleCircleNodes, List<? extends Node> dotTransitions ) {
        this.doubleCircleNodes = doubleCircleNodes;
        this.firstNode = firstNode;
        this.nodes = dotTransitions;
    }
    
    public String createDotString(){
        StringBuilder dotTransitionsBuilder = new StringBuilder();
        dotTransitionsBuilder.append(DOT_HEADER_TEMPLATE);
        for (int i = 0; i < doubleCircleNodes.size(); i++) {
            Node node = doubleCircleNodes.get(i);
            if(i != 0){
                dotTransitionsBuilder
                    .append(BLANK_SPACE);
            }
            dotTransitionsBuilder
                    .append(node.getName());
        }        
        dotTransitionsBuilder.append(DOT_BODY_TEMPLATE);
        appendStartTransition(dotTransitionsBuilder);     
        for (Node node : nodes) { 
            List<? extends Transition> transitions = node.getTransitions();
            for(Transition transition : transitions){
                dotTransitionsBuilder
                    .append(TAB_CHAR)
                    .append(node.getName())
                    .append(TRANSITION_CHAR)
                    .append(transition.getToNodeName())
                    .append(LABEL_OPENER)
                    .append(transition.getTransitionLabel())
                    .append(LABEL_CLOSER);     
            }                          
        }
        return dotTransitionsBuilder.append(DOT_FOOTER_TEMPLATE).toString();    
    }

    private void appendStartTransition(StringBuilder dotTransitionsBuilder) {
        dotTransitionsBuilder
                    .append(TAB_CHAR)
                    .append(INVISIBLE_NODE_NAME)
                    .append(TRANSITION_CHAR)
                    .append(firstNode.getName())
                    .append(LABEL_OPENER)
                    .append(LABEL_CLOSER);
    }
}
